<?php
namespace app\client\controller;
use app\common\lib\Redis;
use think\swoole\facade\Task;
use app\common\lib\InnerCurl;

class Publish extends Base {
    const CHATEXPIRE = 100 * 24 * 3600;
    public function __construct() {
        parent::__construct();
    }
    
    
    public function chat() { //发布说说
        $userType = session('user_type'); //用户类型
        
        $params = request()->post();
        Task::async(function() use($params){
            var_dump($params);
        });
        $chatId = isset($params['chatId']) ? intval($params['chatId']) : 0;
        if($chatId < 0) {
            return errorResult();
        }
        
        
        
        if(!empty($chatId)) {
            $chat = model('Chat')->findOne(['chat_id' => $chatId], ['user_id', 'chat_type']);
            if(empty($chat) || $chat['user_id'] != $this->userid) {
                return errorResult();
            }
            $chatType = $chat['chat_type'];
        }else {
            $chatType = isset($params['chatType']) ? intval($params['chatType']) : 0; //类型 1：普通图文，2：产品图文， 3： LBS红包，4：产品红包，5：砍价，6，抽奖
            if(!in_array($chatType, config('config.chatType'))){
                return errorResult();
            }
        }
        
        
        
        $data = []; //入库的数据
        
        if(in_array($chatType, [1, 2, 3])){ //如果是图文，产品，LBS红包，都可以设置内容，图片，位置
            
            $data['content'] = empty($params['content']) ? '' : htmlspecialchars(trim($params['content']));
            $data['picture'] = isset($params['picture']) ? $params['picture'] : [];
            if(!is_array($data['picture'])){
                return errorResult();
            }
            
            $picCount = count($params['picture']);
            
            if($chatType == 1){ //如果是图文，内容或者图片必须有一种
                if($data['content'] === '' && $picCount == 0){
                    return errorResult('写点东西吧~');
                }
            }
            
            if($chatType == 2){ //如果是产品必须上传图片
                if($picCount == 0){
                    return errorResult('请上传产品图片');
                }
            }
            
            
            if($picCount > 9){ //图片数量最大9张
                return errorResult('图片最多只能9张');
            }
            
            if($picCount > 0){ //设置封面
                $data['cover'] = $data['picture'][0];
            }else{
                $data['cover'] = '';
            }
            
            unset($params['content']);
            unset($params['picture']);
            unset($picCount);
            
            
            if($data['content'] !== '') {
                $redis = new Redis();
                $wx_access_token = $redis->get('wx_access_token');
                $redis->close();
                $ch = curl_init('https://api.weixin.qq.com/wxa/msg_sec_check?access_token=' . $wx_access_token);
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['content' => $data['content']], JSON_UNESCAPED_UNICODE));
                $rs = curl_exec($ch);
                curl_close($ch);
                $rs = json_decode($rs, true);
                if($rs && $rs['errcode'] != 0) {
                    return errorResult('内容含有违法违规内容');
                }
                
                
                
            }
            
            
            
            if(isset($params['location'])){ //位置
                $params['location'] = trim(htmlspecialchars($params['location']));
                if($params['location'] !== ''){
                    $data['location'] = $params['location'];
                }
            }
            
            if(isset($params['longitude'])){
                $params['longitude'] = floatval($params['longitude']);
                if($params['longitude'] !== 0){
                    $data['longitude'] = $params['longitude'];
                }
            }
            
            if(isset($params['latitude'])){
                $params['latitude'] = floatval($params['latitude']);
                if($params['latitude'] !== 0){
                    $data['latitude'] = $params['latitude'];
                }
            }
        }
        
        $time = time();

        $data['user_id'] = $this->userid;
        $data['chat_type'] = $chatType;
        
        if($chatId == 0) {
            $data['create_time'] = $time;
        }
        
        if($chatType == 1){ //发布简单图文
            if(isset($params['reward']) && $params['reward'] === true){ //开启打赏
                $data['reward'] = 1;
            }
            
            $isAdd = false;
            
            if($chatId > 0) { //编辑
               $rs = model('Chat')->modify(['chat_id' => $chatId], $data);
               if($rs === false){
                   return errorResult('编辑失败');
               }
            }else{
                $isAdd = true;
                $chatId = model('Chat')->add($data);
                if(!$chatId){
                    return errorResult('上传失败');
                }
            }
            
            

            $data['chat_id'] = $chatId;
            $CHATEXPIRE = self::CHATEXPIRE;
            Task::async(function() use(&$data, &$CHATEXPIRE, &$isAdd){
                $redis = new Redis();
                $redis->setex('chat_' . $data['chat_id'], $data, $CHATEXPIRE);
                try {
                    if($isAdd === true) {
                        $key = redisUserKey($data['user_id']);
                        $user = $redis->get($key);
                        if(!empty($user)) {
                            $user = json_decode($user, true);
                            $user['chat_number'] += 1;
                            $redis->set($key, $user);
                        }
                    }
                    
                } catch (\Exception $e) {
                }
                $redis->close();
                if($isAdd === true) {
                    InnerCurl::reward('invite', ['id' => $data['user_id']]);
                }
                
                
                return true;
            });
            return successResult('上传成功');
            
        }elseif($chatType == 2){ //产品图文
            return $this->_goods($data, $time, $params, $chatId);
            
        }elseif($chatType == 3){ //红包
            return $this->_redenvelope($data, $time, $params);
            
        }elseif($chatType == 4){ //产品红包，产品红包通过复制选定的商品
            return $this->_goodsRedenvelope($data, $time, $params);
        }elseif($chatType == 5){ //砍价的
            return $this->_bargain($data, $time, $params);
        }elseif($chatType == 6){ //抽奖
            return $this->_luckDraw($data, $time, $params);
        }
        
        
    }
    
    
    /**
     * 商品
     * **/
    
    private function _goods(&$data, &$time, &$params, &$chatId) {
        $_data = [];
        
        $_data['goods_name'] = isset($params['goods_name']) ? trim(htmlspecialchars($params['goods_name'])) : '';
        if(mb_strlen($_data['goods_name']) > 100){
            return errorResult('标题不能超过100个字符');
        }
        
        $_data['goods_no'] = isset($params['goods_no']) ? trim(htmlspecialchars($params['goods_no'])) : '';
        if(mb_strlen($_data['goods_no']) > 15){
            return errorResult('货号长度不能超过15字符');
        }

        $_data['sale_price'] = isset($params['sale_price']) ? floatval($params['sale_price']) : 0;
        if($_data['sale_price'] <= 0.01){
            return errorResult('零售价不能低于0.01元');
        }
        
        if($_data['sale_price'] >= 1000000){
            return errorResult('零售价不能高于1000000元');
        }
        $_data['sale_price'] = round($_data['sale_price'], 2);
        
        
        $_data['agent_price'] = isset($params['agent_price']) ? floatval($params['agent_price']) : 0;
        if($_data['agent_price'] <= 0.01){
            return errorResult('代理价不能低于0.01元');
        }
        
        if($_data['agent_price'] >= 1000000){
            return errorResult('代理价不能高于1000000元');
        }
        $_data['agent_price'] = round($_data['agent_price'], 2);
        
        if(!empty($params['category_id'])){ //分类
            $cateId = intval($params['category_id']);
            $categoryModel = model('ChatCategory');
            if(!$categoryModel->isExistsByPk($cateId)){
                return errorResult('没有分类');
            }
            
            $_data['category_id'] = $cateId;
        }
        
        $isAdd = $chatId == 0 ? true : false;
        
        $chatModel = model('Chat');
        
        $chatModel->startTrans(); //开启事务
        
        try {
            if($isAdd === true) {
                $chatId = $chatModel->add($data);
                if(!$chatId){
                    $chatModel->rollback();
                    return errorResult('上传失败1');
                    
                }
                
                $_data['chat_id'] = $chatId;
                
                $result = model('ChatGoods')->add($_data);
                
                if(!$result){
                    $chatModel->rollback();
                    return errorResult('上传失败2');
                }
                
                if(!empty($_data['category_id'])){
                    $categoryModel->where(['id' => $cateId])->setInc('count');
                }
            }else{
                $rs = $chatModel->modify(['chat_id' => $chatId], $data);
                if($rs === false){
                    $chatModel->rollback();
                    return errorResult('编辑失败');
                }
                
                $goodsModel = model('ChatGoods');
                $goods = $goodsModel->findOne(['chat_id' => $chatId], ['id', 'category_id']);
                $result = $goodsModel->modify(['id' => $goods['id']], $_data);
                
                if($result === false){
                    $chatModel->rollback();
                    return errorResult('编辑失败2');
                }
                
                if(!empty($_data['category_id'])){
                    if($_data['category_id'] != $goods['category_id']) {
                        $categoryModel->where(['id' => $_data['category_id']])->setInc('count');
                        $categoryModel->where(['id' => $goods['category_id']])->setDec('count');
                    }
                }
                
                $_data['chat_id'] = $chatId;
            }
            
            
            $chatModel->commit();
            
            $storeModel = null;
            if(isset($params['add']) && $params['add'] === true){
                $storeModel = model('GoodsStore');
            }
            $CHATEXPIRE = self::CHATEXPIRE;
            
            Task::async(function() use ($data, $_data, $CHATEXPIRE, $storeModel, $isAdd){
                $data = array_merge($data, $_data);
                
                $redis = new Redis();
                $redis->setex('chat_' . $data['chat_id'], $data, $CHATEXPIRE);
                try {
                    if($isAdd === true) {
                        $key = redisUserKey($data['user_id']);
                        $user = $redis->get($key);
                        if(!empty($user)) {
                            $user = json_decode($user, true);
                            $user['chat_number'] += 1;
                            $user['goods_number'] += 1;
                            $redis->set($key, $user);
                        }
                    }
                    
                } catch (\Exception $e) {
                }
                $redis->close();
                
                if($storeModel){ //添加到产品仓库
                    unset($data['chat_id']);
                    $storeModel->add($data);
                }
                
                if($isAdd === true) {
                    InnerCurl::reward('invite', ['id' => $data['user_id']]);
                }
                
                return true;
            });
            
            
            unset($params);
            unset($data);
            unset($_data);
            
            return successResult('上传成功');
            
        } catch (\Exception $e) {
            $chatModel->rollback();
            return errorResult($e->getMessage());
        }
        
    }
    
    /**
     * 红包
     * **/
    private function _redenvelope(&$data, &$time, &$params) {
        $amount = isset($params['amount']) ? floatval($params['amount']) : 0; //红包金额
        $quantity = isset($params['quantity']) ? intval($params['quantity']) : 0; //红包数量
        if($amount <= 0 || $quantity <= 0){
            return errorResult('系统错误1');
        }
        
        if(roundNumber($amount / $quantity) < 0.01){
            return errorResult('单个红包不能小于0.01元');
        }
        
        
        $_data = ['amount' => $amount, 'quantity' => $quantity];
        
        $redenvelopeType = isset($params['type']) ? intval($params['type']) : 1; //类型 1：区域，2：城市，3：全国
        if(!in_array($redenvelopeType, [1, 2, 3])){
            return errorResult();
        }
        $_data['type'] = $redenvelopeType;
        
        if($redenvelopeType == 1){ //附近的红包
            if(empty($data['longitude']) || empty($data['latitude'])){
                return errorResult('请选择位置');
            }
        }elseif($redenvelopeType == 2){ //城市红包
            $cityId = isset($params['cityId']) ? intval($params['cityId']) : 0;
            if($cityId <= 0){
                return errorResult('请选择城市');
            }
            $city = model('Area')->findOne(['id' => $cityId], ['longitude', 'latitude', 'name']);
            $data['location'] = $city['name'];
            $data['longitude'] = $city['longitude'];
            $data['latitude'] = $city['latitude'];
            $_data['city_id'] = $cityId;
        }
        
        $orderNo = getOrderNo($this->userid);
        
        //构建支付订单
        $orderData = [
            'order_no' => $orderNo,
            'user_id' => $this->userid,
            'amount' => $_data['amount'],
            'create_time' => $time,
        ];
        
        $chatModel = model('Chat');
        
        $chatModel->startTrans();
        
        try {
            $result = model('ChatRedenvelopeOrder')->add($orderData); //红包支付订单入库
            if(!$result){
                $chatModel->rollback();
                return errorResult('sss');
            }
            
            //发起支付
            $wxPay = new \app\client\wxpay\WxPayUnifiedOrder(session('user')['openid']);
            $wxPay->setOrder([
                'body' => '测试的支付',
                'order_no' => $orderNo,
                'amount' => $_data['amount'],
                'notify_url' => 'chatRedenvelopeNotify'
            ]);
            
            $payParams = $wxPay->getParams(); //获取发起支付的参数
            
            if($payParams['err']){
                $chatModel->rollback();
                return errorResult('abc');
            }
            
            $redis = new Redis();
            $rs = $redis->setex('redenvelope_' . $orderNo, [$data, $_data], 6000); //支付完成之后，入库说说的数据
            $redis->close();
            if(!$rs){
                $chatModel->rollback();
                return errorResult('ddd');
            }
            
                
            $chatModel->commit();
            
            return successResult(['wxparam' => $payParams['params']]);
                
        } catch (\Exception $e) {
            $chatModel->rollback();
            return errorResult($e->getMessage());
        }
        
    }
    
    
    /**
     * 产品红包
     * **/
    private function _goodsRedenvelope(&$data, &$time, &$params) {
        
        $goodsId = isset($params['id']) ? intval($params['id']) : 0;
        if($goodsId <= 0){
            return errorResult('请选择要发布的产品');
        }
        
        $amount = isset($params['amount']) ? floatval($params['amount']) : 0;
        $quantity = isset($params['quantity']) ? intval($params['quantity']) : 0;
        
        if($amount <= 0 || $quantity <= 0){
            return errorResult();
        }
        
        if(roundNumber($amount / $quantity) < 0.01){
            return '单个红包不能小于0.01元';
        }
        
        $goods = model('GoodsStore')->findOne(['id' => $goodsId]);
        if(!$goods || $goods['user_id'] != $this->userid){
            return errorResult();
        }
        
        $data = ['content' => $goods['content'], 'cover' => $goods['cover'], 'picture' => $goods['picture'], 'user_id' => $this->userid, 'chat_type' => 4, 'create_time' => $time];
        $_data = ['goods_name' => $goods['goods_name'], 'goods_no' => $goods['goods_no'], 'sale_price' => $goods['sale_price'], 'agent_price' => $goods['agent_price']];
        
        $orderNo = getOrderNo($this->userid);
        
        //构建支付订单
        $orderData = [
            'order_no' => $orderNo,
            'user_id' => $this->userid,
            'amount' => $amount,
            'create_time' => $time,
        ];
        
        $chatModel = model('Chat');
        
        $chatModel->startTrans();
        
        try {
            $result = model('GoodsRedenvelopeOrder')->add($orderData);
            if(!$result){
                $chatModel->rollback();
                return errorResult('上传失败');
            }

            //发起支付
            $wxPay = new \app\client\wxpay\WxPayUnifiedOrder(session('user')['openid']);
            $wxPay->setOrder([
                'body' => '测试支付',
                'order_no' => $orderNo,
                'amount' => $amount,
                'notify_url' => 'goodsRedenvelopeNotify'
            ]);
            
            $payParams = $wxPay->getParams();
            
            if($payParams['err']){
                return errorResult();
            }
            
            $redis = new Redis();
            $rs = $redis->setex('goods_redenvelope_' . $orderNo, [$data, $_data, ['amount' => $amount, 'quantity' => $quantity]], 600);
            $redis->close();
            if(!$rs){
                $chatModel->rollback();
                return errorResult();
            }
            
            $chatModel->commit();
            
            return successResult(['wxparam' => $payParams['params']]);
                
        } catch (\Exception $e) {
            $chatModel->rollback();
            return errorResult($e->getMessage());
        }
    }
    
    
    /**
     * 砍价
     * **/
    private function _bargain(&$data, &$time, &$params) {
        $_data = [];
        $goodsId = isset($params['id']) ? intval($params['id']) : 0;
        if($goodsId <= 0){
            return errorResult('请选择要发布的产品');
        }
        
        $_data['stock'] = isset($params['stock']) ? intval($params['stock']) : 0;
        if($_data['stock'] <= 0){
            return errorResult('库存不能小于1');
        }
        
        
        $price = isset($params['bargain_price']) ? floatval($params['bargain_price']) : 0;
        if($price < 0){
            return errorResult('砍价底价不能小于0元');
        }
        
        if($price >= 1000000){
            return errorResult('砍价底价不能高于1000000元');
        }
        
        /* $_data['bargain_count_limit'] = isset($params['bargain_count_limit']) ? intval($params['bargain_price']) : 0;
        if($_data['bargain_count_limit'] <= 0){
            return errorResult('砍价人数不能小于1');
        } */
        
        $_data['start_time'] = isset($params['start_time']) ? strtotime($params['start_time']) : 0;
        /* if($_data['start_time'] <= $time){
            return errorResult('请选择合适的开始时间');
        } */
        
        $_data['end_time'] = isset($params['end_time']) ? strtotime($params['end_time']) : 0;
        if($_data['end_time'] <= $_data['start_time']){
            return errorResult('请选择合适的结束时间');
        }
        
        $_data['end_time'] = strtotime('+1 day', $_data['end_time']);
        
        $_data['expire'] = isset($params['expire']) ? floatval($params['expire']) : 0; //多少小时
        if($_data['expire'] <= 0){
            return errorResult('请设置合适有效期');
        }
        
        $_data['user_id'] = $this->userid;
        
        $goods = model('GoodsStore')->findOne(['id' => $goodsId]); //没有此商品
        if(!$goods){
            return errorResult();
        }
        
        unset($params);
        
        $data['cover'] = $goods['cover'];
        $data['content'] = $goods['content'];
        $data['picture'] = $goods['picture'];
        $data['cover'] = $goods['cover'];
        
        $chatGoods['goods_no'] = $goods['goods_no'];
        $chatGoods['goods_name'] = $goods['goods_name'];
        $chatGoods['sale_price'] = $goods['sale_price'];
        $chatGoods['agent_price'] = $goods['agent_price'];
        $chatGoods['bargain_price'] = $price;
        
        $chatModel = model('Chat');
        
        $chatModel->startTrans(); //开启事务
        
        try {
            $chatId = $chatModel->add($data);
            if(!$chatId){
                $chatModel->rollback();
                return errorResult();
            }
            
            $chatGoods['chat_id'] = $chatId;
            $rs = model('ChatGoods')->add($chatGoods);
            if(!$rs){
                $chatModel->rollback();
                return errorResult();
            }
            
            $_data['chat_id'] = $chatId;
            
            $rs = model('ChatBargain')->add($_data);
            if(!$rs){
                $chatModel->rollback();
                return errorResult();
            }
            
            
            //加入redis缓存
            $redis = new Redis();
            $redis->setex('chat_' . $chatId, array_merge($data, $_data, $chatGoods), self::CHATEXPIRE);
            $redis->close();
            
            $chatModel->commit();
            
            return successResult('上传成功');
            
        } catch (\Exception $e) {
            $chatModel->rollback();
            return errorResult($e->getMessage());
        }
    }
    
    /**
     * 抽奖
     * **/
    private function _luckDraw(&$data, &$time, &$params) {
        $_data = ['user_id' => $this->userid];
        $goodsId = isset($params['id']) ? intval($params['id']) : 0;
        if($goodsId <= 0){
            return errorResult('请选择要抽奖的产品');
        }
        
        $_data['number'] = isset($params['number']) ? intval($params['number']) : 0;
        if($_data['number'] <= 0){
            return errorResult('中奖商品数量不能少于1');
        }
        
        
        $_data['total'] = isset($params['total']) ? floatval($params['total']) : 0;
        if($_data['total'] < 0){
            return errorResult('抽奖总人数不能少于1');
        }
        
        
        $_data['start_time'] = isset($params['start_time']) ? strtotime($params['start_time']) : 0;
        /* if($_data['start_time'] <= $time){
         return errorResult('请选择合适的开始时间');
         } */
        
        $_data['end_time'] = isset($params['end_time']) ? strtotime($params['end_time']) : 0;
        if($_data['end_time'] <= $_data['start_time']){
            return errorResult('请选择合适的结束时间');
        }
        
        $_data['end_time'] = strtotime('+1 day', $_data['end_time']);
        
        
        $goods = model('GoodsStore')->findOne(['id' => $goodsId]); //没有此商品
        if(!$goods){
            return errorResult();
        }
        
        unset($params);
        
        $data['cover'] = $goods['cover'];
        $data['content'] = $goods['content'];
        $data['picture'] = $goods['picture'];
        $data['cover'] = $goods['cover'];
        
        $chatGoods['goods_no'] = $goods['goods_no'];
        $chatGoods['goods_name'] = $goods['goods_name'];
        $chatGoods['sale_price'] = $goods['sale_price'];
        $chatGoods['agent_price'] = $goods['agent_price'];
        
        $chatModel = model('Chat');
        
        $chatModel->startTrans(); //开启事务
        
        try {
            $chatId = $chatModel->add($data);
            if(!$chatId){
                $chatModel->rollback();
                return errorResult('a');
            }
            
            $chatGoods['chat_id'] = $chatId;
            $rs = model('ChatGoods')->add($chatGoods);
            if(!$rs){
                $chatModel->rollback();
                return errorResult('b');
            }
            
            $_data['chat_id'] = $chatId;
            
            $rs = model('ChatLuckDraw')->add($_data);
            if(!$rs){
                $chatModel->rollback();
                return errorResult('c');
            }
            
            $CHATEXPIRE = self::CHATEXPIRE;
            
            Task::async(function() use(&$chatId, &$data, &$_data, &$chatGoods, $CHATEXPIRE) {
                $probability = [];
                for ($i = 1; $i <= $_data['total']; $i ++) {
                    if($i <= $_data['number']) {
                        array_push($probability, 1);
                    }else{
                        array_push($probability, 0);
                    }
                }

                shuffle ($probability);
                shuffle ($probability);
                
                
                $key = 'chat_luck_draw_' . $chatId;
                //加入redis缓存
                $redis = new Redis();
                $redis->setex('chat_' . $chatId, array_merge($data, $_data, $chatGoods), $CHATEXPIRE);
                foreach ($probability as $item) {
                    $redis->lpush($key, $item);
                }
                $redis->handler()->expireAt($key, $_data['end_time']);
                $redis->close();
            });
            
            $chatModel->commit();
            
            return successResult('上传成功');
            
        } catch (\Exception $e) {
            $chatModel->rollback();
            return errorResult($e->getMessage());
        }
    }
    
    public function editInfo() {
        $chatId = request()->route('chatId', 0, 'intval');
        if($chatId <= 0) {
            return errorResult();
        }
        
        $chat = model('Chat')->findOne(['chat_id' => $chatId]);
        if(empty($chat) || $chat['chat_id'] != $chatId || !in_array($chat['chat_type'], [1, 2])) {
            return errorResult();
        }
        
        if($chat['chat_type'] == 2) {
            $goods = model('ChatGoods')->findOne(['chat_id' => $chatId], ['goods_name', 'goods_no', 'category_id', 'sale_price', 'agent_price']);
            if(empty($goods)) {
                return errorResult();
            }
            
            if(!empty($goods['category_id'])) {
                $goods['category_name'] = model('ChatCategory')->where(['id' => $goods['category_id']])->value('name');
            }
            
            $chat = array_merge($chat, $goods);
        }
        
        return successResult($chat);
    }
    
}













